import { Component, ElementRef, Input, Renderer2, TemplateRef, ViewChild } from '@angular/core';
import { ApesField } from './apes-field';
import { ApiService } from '@core/services/http/api.service';
import { Events } from '@core/services/events/Events';
import { ExpressionService } from '@core/services/expression/ExpressionService';
import { SubjectService } from '@core/services/events/subject.service';
import { Subject } from 'rxjs/internal/Subject';
import { of } from 'rxjs/internal/observable/of';
import { getO, getText, getValueUsingField, missing, replaceAll, type, deepClone } from '../../../../utils/utils';
import { catchError, debounceTime, distinctUntilChanged, map, switchMap, tap } from 'rxjs/operators';
import { SearchService } from '@core/services/search.service';
import {
  addDays,
  endOfDay, isDate,
  startOfDay,
} from 'date-fns';
import { toBoolean } from '@shared/apes/core';
import { ApesDialogCascaderComponent } from '@shared/dialog-cascader/apes-dialog-cascader.component';
import { fillField } from '../../../../utils/utils';
import { UserAuthService } from '@core/services/user-auth.service';

@Component({
  selector: 'formly-field-condition-input',
  template: `
    <div apes-col [apesMd]="getDivCol()">
      <apes-form-item style="margin-bottom:0px;">
        <apes-form-label *ngIf="to.label !=''" apes-col [apesMd]="getLblCol()" [apesRequired]="required">
          <span>{{to.label}}</span>
          <span *ngIf="tooltip != ''"><i apes-icon apesType="info-circle" apes-tooltip
                                         [apesTooltipTitle]="titleTemplate"
                                         class="condition-input-tip"></i></span>
          <ng-template #titleTemplate>
            <span [innerHTML]="tooltip"></span>
          </ng-template>
        </apes-form-label>

        <div *ngIf="to.label =='' && showEmptyLabel" apes-col [apesMd]="getLblCol()">
          <span></span>
        </div>

        <apes-form-control apes-col [apesMd]="6" *ngIf=" getOperators(to.config).length > 1 ">
          <ng-select [items]="getOperators(to.config)" [(ngModel)]='to.config.value' [placeholder]="'请选择条件'">
          </ng-select>
        </apes-form-control>

        <apes-form-control apes-col [apesMd]=" getOperators(to.config).length > 1 ? 10 : getInputCol()">

          <ng-container [ngSwitch]="to.config.type">

            <!--输入框-->
            <input #focusKey apes-input [formControl]="formControl" [formlyAttributes]="field" *ngSwitchCase='"string"'
                   [placeholder]="to.placeholder"/>

            <!--<input apes-input [formControl]="formControl" [formlyAttributes]="field" *ngSwitchCase='"number"'-->
            <!--[placeholder]="to.placeholder"/>-->

            <!--输入查询弹框-->
            <apes-input-group apesSearch [apesSuffix]="suffixIconButton" *ngSwitchCase='"search"'>
              <input apes-input [placeholder]="to.placeholder" [formControl]="formControl" [formlyAttributes]="field">
              <ng-template #suffixIconButton>
                <i apes-icon class="condition-input-search" apesType="search" (click)="onSearch()"></i>
              </ng-template>
            </apes-input-group>

            <!--数字框-->
            <apes-input-number style="width: 100%" [formControl]="formControl" [formlyAttributes]="field"
                               *ngSwitchCase='"number"'
                               [apesPlaceHolder]="to.placeholder"></apes-input-number>

            <!--勾选框-->
            <label apes-checkbox [formControl]="formControl" [formlyAttributes]="field"
                   *ngSwitchCase="'boolean'">{{ to.title }}</label>

            <!--多选框-->
            <checkbox [formControl]="formControl"
                      [items]="items" [showSelectAll]="showSelectAll" *ngSwitchCase='"checkbox"'>
            </checkbox>

            <!--单选框-->
            <apes-radio-group style="width: 100%; height: 40px;" [formControl]="formControl"
                              (ngModelChange)="setCheck($event)"
                              *ngSwitchCase='"radio"'>{{ to.title }}
              <div apes-row>
                <ng-container *ngFor="let item of  items">
                  <div apes-col [apesSpan]="item.span? item.span:8">
                    <label apes-radio [apesValue]="item.id">{{item.name}}</label>
                  </div>
                </ng-container>
              </div>
            </apes-radio-group>

            <!--日期框-->
            <apes-date-picker [apesStyle]="{width: '100%'}" apesFormat="yyyy-MM-dd" [formControl]="formControl"
                              [formlyAttributes]="field" *ngSwitchCase="'date'"
                              [apesPlaceHolder]="to.placeholder"></apes-date-picker>

            <!--月份框-->
            <apes-month-picker [formControl]="formControl" [apesPlaceHolder]="to.placeholder"
                               [formlyAttributes]="field" *ngSwitchCase="'month'"></apes-month-picker>

            <!-- 年份框-->
            <apes-year-picker [formControl]="formControl" [apesPlaceHolder]="to.placeholder"
                              [formlyAttributes]="field" *ngSwitchCase="'year'"></apes-year-picker>

            <!--日期组框-->
            <apes-range-picker [apesStyle]="{width: '100%'}" [apesFormat]="formatType" [formControl]="formControl"
                               [apesShowTime]="showTime"
                               [apesPlaceHolder]="to.placeholder" [apesRanges]="dateRange"
                               [formlyAttributes]="field" *ngSwitchCase="'dateRange'"></apes-range-picker>

            <!--月份组框-->
            <apes-month-picker [apesPlaceHolder]="to.placeholder"
                               [apesDisabledDate]="disabledStartDate"
                               [(ngModel)]="startValue"
                               (ngModelChange)="onStartChange($event)"
                               (apesOnOpenChange)="handleStartOpenChange($event)"
                               *ngSwitchCase="'monthRange'" class="apes-monthRange"></apes-month-picker>

            <apes-month-picker [apesPlaceHolder]="to.placeholder"
                               [apesDisabledDate]="disabledEndDate"
                               [(ngModel)]="endValue"
                               [apesOpen]="endOpen"
                               (ngModelChange)="onEndChange($event)"
                               (apesOnOpenChange)="handleEndOpenChange($event)"
                               *ngSwitchCase="'monthRange'" class="apes-monthRange"></apes-month-picker>

            <!--选择框-->
            <ng-select [items]="items" [formControl]="formControl" [formlyAttributes]="field" *ngSwitchCase="'select'"
                       [placeholder]="to.placeholder || '请输入编码或名称'"
                       [multiple]="to.config.multiple"
                       [closeOnSelect]="closeOnSelect"
                       (scrollToEnd)="scrollToBottom()"
                       [typeahead]="contractinput$"
                       [loading]="contractLoading"
                       [optionWidth]="width"
                       [bindValue]="bindValue"
                       [searchBtn]="to.config.searchFormId"
                       (searchBtnFn)="onSearch()"
                       (change)="setName($event)">
              <ng-template ng-label-tmp let-item="item" let-clear="clear">
                <span class="ng-value-label">{{formatter(item, getValueFormatter())}}</span>
                <span class="ng-value-icon right" (click)="clear(item)" aria-hidden="true">×</span>
              </ng-template>
              <ng-template ng-option-tmp let-item="item">
                <div class="ng-option-flex">
                  <span class="ng-value-label">{{formatter(item, getDownFormatter())}}</span>
                  <span *ngIf="showRight" style="text-align: right">{{formatter(item, getDownRightFormatter())}}</span>
                </div>
              </ng-template>
            </ng-select>

            <!--树形选择框-->
            <apes-tree-select [apesNodes]="nodes" style="width: 100%"
                              [formControl]="formControl"
                              apesShowSearch="true"
                              apesShowLine
                              [apesMultiple]="multiple"
                              [apesDisplayWith]="treeDisplay"
                              *ngSwitchCase="'tree-select'">
            </apes-tree-select>

            <!--树形选择框-->
            <apes-tree [apesData]="nodes" style="width: 100%"
                       [formControl]="formControl"
                       (apesClick)="onTreeSelect($event)"
                       *ngSwitchCase="'tree'"></apes-tree>

            <!--富文本框-->
            <textarea apes-input
                      class="apes-input-readonly"
                      [rows]="Rows"
                      [cols]="to.config.cols"
                      [value]="textareaValue"
                      readonly="readonly"
                      *ngSwitchCase="'important-note'"></textarea>

            <!--列表按钮框-->
            <div *ngSwitchCase="'label-list'" apes-col [apesSpan]="getInputCol()">
              <div *ngFor="let item of items" class="apes-label-list-item">
                <apes-card apes-col [apesSpan]="getLabelListCol()" class="apes-label-list"
                           [ngClass]="{'active': item.checked }"
                           (click)="setLabelListCheck(item,$event)">
                  <!--                  <div>{{item.value ? item.value : 0}}</div>-->
                  <!--                  <div>{{item.name}}</div>-->
                  <div>
                    {{item.name}}
                    <span *ngIf="!filterType && !hideValue">({{item.value ? item.value : 0}})</span>
                  </div>
                </apes-card>
              </div>
            </div>

            <!--按钮框-->
            <ng-container *ngSwitchCase="'button'">
              <button *ngIf="checkBtnStatus()" apes-button
                      [apesLoading]="btnLoading"
                      [apesType]="btnType"
                      (click)="clickBtn()">{{btnName}}</button>
            </ng-container>


          </ng-container>

        </apes-form-control>
      </apes-form-item>
    </div>

  `,
  styles: [`
    .ng-option-flex {
      display: flex;
      line-height: 15px;
    }

    .ng-option-flex span {
      flex: 1;
    }

    .condition-input-tip {
      position: relative;
      top: 1px;
      padding: 2px;
      color: #e6a23c;
      cursor: pointer;
    }

    .condition-input-search {
      cursor: pointer;
    }

    .apes-label-list-item {
      margin-bottom: 0;
    }

    .apes-label-list {
      text-align: center;
      border-radius: 5px;
      padding: 4px;
      font-weight: bold;
      cursor: pointer;
      margin-right: 8px;
    }

    .apes-label-list.active {
      background: rgba(5, 137, 221, 0.35);
    }

    .apes-monthRange {
      width: 50%;
    }
  `],
  host: {},
})

export class FormlyFieldConditionInput extends ApesField {
  treeDisplay = (node) => '[' + node.key + ']' + node.title;
  private value: any; // 用于设置默认值
  private _current = 0;
  private _pages = 0;
  private _pageSize = 20;
  items: any[] = [];   // select控件的数据源
  contractinput$ = new Subject<string>();
  private _searchText = '';
  contractLoading = false;
  private _domain;
  api: string;
  private multiple = false;
  private bindValue: string = 'id';
  showRight = false;
  closeOnSelect: boolean = true;
  width = 0;
  nodes = [
    {
      title: '数据加载中',
      value: '0-0',
      key: '0-0',
      children: [
        {
          title: 'Child Node1',
          value: '0-0-1',
          key: '0-0-1',
        },
        {
          title: 'Child Node2',
          value: '0-0-2',
          key: '0-0-2',
        },
      ],
    },
  ];
  tooltip = '';
  formatType: string = 'yyyy-MM-dd';
  showTime = false;

  startValue: Date | null = null;
  endValue: Date | null = null;
  endOpen = false;
  showSelectAll: boolean = true;

  btnType: any;
  btnName: any;
  btnLoading: any;

  filterType: boolean = false;
  hideValue: boolean = false;

  showEmptyLabel: boolean = false;

  platform: any;


  @ViewChild('focusKey', { static: false }) focusKey: ElementRef;

  get required() {
    let bRequired = false;
    if (!this.to.config.required) return;
    if (typeof this.to.config.required == 'boolean') {
      bRequired = this.to.config.required;
    } else if (typeof this.to.config.required == 'string') {
      bRequired = this.expressionService.evaluate(this.to.config.required, {
        context: this.formState,
        form: this.form,
        model: this.model,
        data: null,
      }, false);
    }

    this.to.required = bRequired;
    return bRequired;
  }

  private dateRange = {
    '当天': [startOfDay(new Date()), endOfDay(new Date())],
    '近7天': [addDays(new Date(), -6), endOfDay(new Date())],
    '近30天': [addDays(new Date(), -29), endOfDay(new Date())],
    '近90天': [addDays(new Date(), -89), endOfDay(new Date())],
  };

  constructor(
    protected apiService: ApiService,
    protected events: Events,
    protected expressionService: ExpressionService,
    protected subject: SubjectService,
    protected searchService: SearchService,
    protected userService: UserAuthService,
    protected elementRef: ElementRef,
    protected renderer: Renderer2) {
    super(apiService, events, expressionService, subject);
    this.loadContract();
  }

  ngOnInit() {
    this.platform = this.userService.getUserInfoObj() ? this.userService.getUserInfoObj().platform : '';
    /*** 下拉默认设置 ***/
    if (this.to.config.type === 'select') {
      this.bindValue = this.to.config.bindValue ? this.to.config.bindValue : 'id';
      const config = this.to.config;
      this.api = config.api;
      this.multiple = config.multiple === 'true' || false;
      this.closeOnSelect = config.hasOwnProperty('closeOnSelect') ? config.closeOnSelect : true;
      if (this.to['domain']) {
        config['domain'] = replaceAll(this.to.domain, '\'', '');
        this._domain = JSON.parse(config.domain);
      }

      //对于选择枚举或者数量极少的数据,进行提前查出
      if (config.api && config.autoSearch) {
        // 可以接受传入条件(包括域)，需要在 XML 中配置条件值(默认查询三十条数据用于查询出所有的枚举数据)
        const options = { page: this._current, size: 50 };
        if (this._domain) {
          const group = this.fillField(this._domain);
          if (!(group.filters.length === 0 && group.groups.length === 0)) {
            options['domain'] = group;
          }
        }
        this.apiService.post(config.api, { 'body': JSON.stringify(options) }).subscribe(
          (body) => {
            if (body) {
              this.items = body.content;
              this._current = body.page + 1;
              this._pages = body.pages;
            }
          });
      } else if (config.items) {
        // this.items = config.items;
        this.items = getO(config.items);
      }
      if (this.to.config.hasOwnProperty('downRightFormatter')) {
        this.showRight = true;
      }
      this.width = this.to.config.width;
    } else if (this.to.config.type === 'checkbox' || this.to.config.type === 'radio' || this.to.config.type === 'label-list') {
      if (this.to.config.type === 'checkbox' && this.to.config.hasOwnProperty('showSelectAll')) {
        this.showSelectAll = this.to.config['showSelectAll'];
      }
      if (this.to.config.type === 'label-list' && this.to.config.hasOwnProperty('hideValue')) {
        this.hideValue = true;
      }
      this.items = getO(this.to.config['items']);
    } else if (this.to.config.type === 'tree-select') {
      this.multiple = !!this.to.config.multiple;
    } else if (this.to.config.type === 'dateRange' && this.to.config.hasOwnProperty('valueFormatter')) {
      this.formatType = this.to.config['valueFormatter'];
      this.showTime = true;
    } else if (this.to.config.type === 'search') {
      this.bindValue = this.to.config.bindValue ? this.to.config.bindValue : 'id';
    } else if (this.to.config.type === 'button') {
      this.addEventListener(this.elementRef, this.renderer);
      this.btnType = this.to.config.btnType ? this.to.config.btnType : 'primary';
      this.btnName = this.to.config.btnName ? this.to.config.btnName : '查找';
    }
    if (this.to.config.hasOwnProperty('showEmptyLabel')) {
      this.showEmptyLabel = true;
    }
    if (this.to['defaultValue'] !== undefined && this.to['defaultValue'] !== null) {
      this.checkDefaultValue();
      this.subject.subscribe(this.formState, 'defaultValue', data => {
        this.checkDefaultValue(false);
      });
    } else {
      this.value = null;
    }
    if (this.to.config.hasOwnProperty('tooltipFormatter')) {
      this.tooltip = this.to.config.tooltipFormatter;
    }
    if (this.model && this.model[this.key] && this.model[this.key + '_name']) {
      if (this.to.config.multiple && !this.to.config.init) {
        this.items = [];
        for (let i = 0; i < this.model[this.key].length; i++) {
          this.items.push({ id: this.model[this.key][i], name: this.model[this.key + '_name'][i] });
        }
      } else {
        if (!this.to.config.init) {
          this.items = [{ id: this.model[this.key], name: this.model[this.key + '_name'] }];
        }
      }
    }

    if (this.to.config.type === 'label-list') {
      this.subject.subscribe(this.formState, 'labelListData', data => {
        // console.log(this.to.config);
        if (this.items.length != 0) {
          this.items.forEach((item) => {
            if (data.length > 0) {
              data.forEach((res) => {
                if (item.id == res.id) {
                  item['value'] = res.value;
                }
              });
            } else {
              item['value'] = 0;
            }
          });
        } else {
          let multiple = false;
          data.forEach((res) => {
            if (res.key) multiple = true;
            if (res.key && this.key == res.key) {
              this.items.push(res);
            }
          });
          if (!multiple) {
            this.items = data;
          }
        }
      });
    }
    this.addEventListener(this.elementRef, this.renderer);
  }

  ngAfterViewInit() {
    const config = this.to.config;
    // 增加 init xml 选项，表示不搜索下拉， 默认查询api作为下拉选项
    if ((config.type === 'select') && config['init'] && config.api) {
      this.getItemData();
    }
    if ((config.type == 'tree-select') && config.api) {
      this.getTreeData();
    }
    if (config.hasOwnProperty('filterType')) {
      this.filterType = true;
      if (config.type == 'tree') {
        if (config.type == 'tree') {
          this.getTreeData();
          this.subject.subscribe(this.formState, 'resetForm', data => {
            this.nodes = [];
            this.getTreeData();
          });
        }
      } else if (config.type == 'label-list') {
        this.getFilterData();
        this.subject.subscribe(this.formState, 'resetForm', data => {
          this.getFilterData();
        });
      }
    }

    if (config.hasOwnProperty('editFocus')) {
      setTimeout(() => {
        console.log('editFocus');
        this.focusKey.nativeElement.focus();
      }, 1000);
    }
  }

  getDivCol() {
    return this.to.col || this.to.divCol || 8;
  }

  getLblCol() {
    return this.to.lblCol || 6;
  }

  getInputCol() {
    return this.to.inputCol || 16;
  }

  getLabelListCol() {
    // return {
    //   gutter: 16,
    //   span: this.to.config.labelListCol ? this.to.config.labelListCol : 4,
    // };
    return this.to.config.labelListCol ? this.to.config.labelListCol : 4;
  }

  typeMap: { [key: string]: string } = {
    string: 'text',
    number: 'number',
    select: 'select',
    date: 'date',
    month: 'month',
    year: 'year',
    boolean: 'checkbox',
  };
  operatorMap: { [key: string]: string[] } = {
    string: ['EQ', 'NE', 'LIKE', 'PARENT'],
    number: ['EQ', 'NE', 'GT', 'GTE', 'LT', 'LTE'],
    category: ['EQ', 'NE'],
    date: ['EQ', 'NE', 'GT', 'GTE', 'LT', 'LTE'],
    month: ['EQ', 'NE', 'GT', 'GTE', 'LT', 'LTE'],
    year: ['EQ', 'NE', 'GT', 'GTE', 'LT', 'LTE'],
    'important-note': [],
  };

  /***
   * 处理操作符
   * @param config
   * @returns {string[]}
   */
  getOperators(config: any): string[] {
    let operators = [];

    if (config.operators && config.operators.length > 0) {
      operators = config.operators;
      return operators;
    }

    if (config.type) {
      operators = this.operatorMap[config.type];
    }

    if (config.nullable) {
      operators = operators.concat(['is null', 'is not null']);
    }

    if (config.inable) {
      operators = operators.concat(['in', 'not in']);
    }

    return operators;
  }

  /***
   * 滚动加载数据
   */
  scrollToBottom() {
    if (this._current === this._pages) return;
    if (!this.api) return;
    const data = this.getApiParams();
    this.apiService.post(this.to.config.api, { 'body': JSON.stringify(data) }).subscribe(
      (body) => {
        if (body) {
          if (body.page === 0) {
            this.items = [];
          }
          this.items = this.items.concat(body.content);
          this._current = body.page + 1;
          this._pages = body.pages;
        }
      });
  }

  /***
   * 数据格式化
   * @returns {string}
   */

  getDownFormatter(): string {
    return this.to.config.downFormatter || '\'[ \' + value.id + \' ]\' + \' \' + value.name';
  }

  getDownRightFormatter() {
    return this.to.config.downRightFormatter || '\'[ \' + value.id + \' ]\' + \' \' + value.name';
  }

  getValueFormatter(): string {
    return this.to.config.valueFormatter || '\'[ \' + value.id + \' ]\' + \' \' + value.name';
  }

  formatter(value: any, expression: string) {
    return this.expressionService.evaluate(expression, {
      context: {},
      model: {},
      value: value,
    });
  }


  /***
   * 功能： 加载数据
   */
  private loadContract() {
    this.contractinput$.pipe(
      debounceTime(500),
      distinctUntilChanged(),
      tap(() => this.contractLoading = true),
      switchMap((term) => {
        if (missing(term)) {
          this.contractLoading = false;
          return of([]);
        }
        term = this.trim(term);
        if (!this.api) return of(this.items); // 当前Api不存在直接返回
        if (this._searchText === term) {
          this.contractLoading = false;
          return of(this.items);
        }
        this._current = 0;
        this._searchText = term;
        const data = this.getApiParams();
        return this.apiService.post(this.api, data).pipe(
          map((res) => {
              this.items = [];
              this._searchText = term;
              this.items = this.items.concat(res.content);
              if (this.to.config.multiple) {
                const key = this.to.componentRef.field.key;
                if (this.model[key] !== null && this.model[key] !== undefined && this.model[key].length > 0) {
                  let items = [];
                  let isUpperCase: boolean = !this.getValueFormatter().includes('id');
                  for (let i = 0; i < this.model[this.key].length; i++) {
                    let obj = {};
                    if (isUpperCase) {
                      obj = { ID: this.model[this.key][i], NAME: this.model[this.key + '_name'][i] };
                    } else {
                      obj = { id: this.model[this.key][i], name: this.model[this.key + '_name'][i] };
                    }
                    items.push(obj);
                  }
                  items.forEach((item) => {
                    let check = true;
                    this.items.forEach((i) => {
                      if (isUpperCase && item.ID == i.ID) {
                        check = false;
                      } else if (!isUpperCase && item.id == i.id) {
                        check = false;
                      }
                    });
                    if (check) {
                      this.items.push(item);
                    }
                  });
                }
              }
              this._current = res.page + 1;
              this._pages = res.pages;
              return res.content;
            },
          ),
          catchError(() => of([])), // empty list on error
          tap(() => this.contractLoading = false),
        );
      }),
    ).subscribe();
  }

  // 用于处理前后空格
  trim(text) {
    if (text.trim) {
      return text.trim();
    } else {
      let reg = /^\s+|\s+$/g;
      return text.replace(reg, '');
    }
  }

  /***
   * 获取当前页码以及域
   * @returns {{key: string; page: number; size: number}}
   */
  private getApiParams() {
    const data = { key: this._searchText, page: this._current, size: this._pageSize };
    if (this._domain) {
      const group = this.fillField(this._domain);
      data['group'] = group;
    }
    return data;
  }

  getItemData() {
    const data = this.getApiParams();
    this.apiService.post(this.to.config.api, data).subscribe(item => {
      this.contractLoading = false;
      if (item != undefined) {
        if (item.page === 0) {
          this.items = [];
        }
        this.items = this.items.concat(item.content);
        this._current = item.page + 1;
        this._pages = item.pages;
      }
    });
  }

  getTreeData() {
    this.apiService.post(this.to.config.api, { lastStage: this.to.config.hasOwnProperty('lastStage') }).subscribe(item => {
      this.nodes = item;
    });
  }


  getFilterData() {
    this.apiService.post(this.to.config.api, {}).subscribe(item => {
      this.items = item;
    });
  }


  onTreeSelect(e) {
    let value = e.node.isSelected ? e.node.key : null;
    this.formControl.patchValue(value);
    this.subject.publish(this.formState, 'filterSelected', e);
  }

  /***
   * 功能: 处理域
   * @param domain
   * @param searchFlag
   * @returns {any}
   */
  private fillField(domain: any, searchFlag: boolean = false) {
    let result;
    if (type(domain) === 'object') {
      result = {};
    } else {
      result = [];
    }
    for (const key in domain) {
      let value = domain[key];
      const t = type(value);
      if (t === 'object') {
        value = this.fillField(value, searchFlag);
      } else if (t === 'array') {
        value = [...this.fillField(value, searchFlag)];
      } else {
        if (t === 'string') {
          const text = getText(value);
          if (text) {
            if (text === 'value') {
              if (searchFlag) return;
              value = this._searchText;
            } else {
              value = getValueUsingField(this.formState, text, true);
            }
          }
        }
      }

      let val = value;
      if (type(value) === 'array') {
        if (type(val) === 'array') {
          // 对解析出的数据做出筛选
          val = val.filter((elem) => {
              if (elem == undefined) return false;
              if (isDate(elem)) return true;
              if (type(elem) === 'object') {
                if (elem.hasOwnProperty('value')) {
                  return elem.value !== null && elem.value !== undefined; //&& elem.value !==''
                } else {
                  if (elem !== undefined) return true;
                }
              }
              if (type(elem) === 'string') {
                if (elem !== '') return true;
              }
            },
          );
        }
        value = val;
      } else if (type(value) === 'object' && val != null && val.filters) {
        if (val.filters.length === 0) {
          if (val.groups.length === 0) {
            val = [];
          } else {
            val.filters = val.groups;
            val.groups = [];
          }
        }
      }

      if (key === 'groups' && val[0] && val[0].length === 0) {
        result[key] = [];
      } else {
        result[key] = val;
      }
    }
    // console.log(result);
    return result;
  }

  setName(param) {
    if (param) {
      let multiple = this.to.config.multiple;
      if (multiple) {
        this.model[this.key + '_name'] = [];
        param.forEach((p) => {
          let value = p.name ? p.name : p.NAME;
          this.model[this.key + '_name'].push(value);
        });
      } else {
        this.model[this.key + '_name'] = param.name ? param.name : param.NAME;
      }
    } else {
      if (this.to.config.hasOwnProperty('items')) {
        let items = this.to.config.items;
        this.items = getO(items);
      }
    }
  }

  /*
  * 弹窗查找,回写数据
  * */
  onSearch() {
    this._searchText = '';
    const key = this.to.componentRef.field.key;
    const options = { multiple: this.to.config.multiple };
    if (this._domain) {
      const group = fillField(this._domain, true);
      if (!(group.filters.length === 0 && group.groups.length === 0)) {
        options['domain'] = group;
      }
    }
    // 弹窗api与下拉api保持一致
    options['api'] = this.to.config.api;
    let dialog;

    // 定制弹框页面直接调用api
    if (this.to.config['dialogType'] === 'cascader') {
      // options['dialogConfig'] = JSON.parse(this.to.config['dialogConfig']);
      dialog = ApesDialogCascaderComponent;
      options['id'] = this.to.config.searchFormId;
    }

    if (this.to.config.uniqueKey) {
      options['uniqueKey'] = this.to.config.uniqueKey;
      options['addSame'] = this.to.config.addSame == false ? this.to.config.addSame : true;
      if (this.to.config.hasOwnProperty('valueFormatter')) {
        options['valueFormatter'] = this.to.config.valueFormatter;
      }
    }

    this.searchService.openDialog(this.to.config.searchFormId, options, (result: any) => {
      if (result && result.length > 0) {
        const items = deepClone(this.items);
        this.items = [];
        for (let i = 0, len = result.length; i < len; i++) {
          this.items = this.items.concat(result[i]);
        }
        if (this.to.config.multiple) {
          let isUpperCase = key.toUpperCase();
          if (this.model[key] !== null && this.model[key] !== undefined && this.model[key].length > 0) {
            // const items = deepClone(this.model[key]);
            for (let i = 0; i < this.model[this.key].length; i++) {
              let obj = {};
              if (isUpperCase) {
                obj = { ID: this.model[this.key][i], NAME: this.model[this.key + '_name'][i] };
              } else {
                obj = { id: this.model[this.key][i], name: this.model[this.key + '_name'][i] };
              }
              this.items.push(obj);
            }
            // this.items = items.concat(this.items);
          }
          if (this.to.config.type == 'search') {
            let value = '';
            this.items.forEach((item) => {
              value += item[this.bindValue] + ';';
            });
            this.form.get(key).patchValue(value);
          } else {
            this.form.get(key).patchValue(this.items.map(item => item[this.bindValue]));
            this.model[this.key + '_name'] = [];
            this.items.map((item) => {
              let name = isUpperCase ? item['NAME'] : item['name'];
              this.model[this.key + '_name'].push(name);
            });
          }
        } else {
          // bindValue = "id" 所以这里的值为id
          this.form.get(key).patchValue(this.items[0][this.bindValue]);
        }
      }
    }, dialog ? dialog : null).subscribe();
  }

  setCheck(param) {
    if (this.key === '_showType' && param) {
      let data = this.items.filter(item => item.id == param)[0];
      this.subject.publish(this.formState, 'changeShowType', data);
    }
  }

  clickBtn() {
    this.subject.publish(this.formState, 'clickBtn', this.key);
  }

  setLabelListCheck(param, e) {
    e.stopPropagation();
    if (param.checked) {
      this.formControl.patchValue('');
    } else {
      this.formControl.patchValue(param.id);
    }
    if (this.to.config.type === 'label-list') {
      let data;
      this.items.forEach((item) => {
        if (item.id == param.id && !param.checked) {
          item['checked'] = true;
          data = item;
          if (data.hasOwnProperty('api')) {
            data['showType'] = true;
          }
        } else {
          item['checked'] = false;
        }
      });
      if (this.filterType) {
        this.subject.publish(this.formState, 'filterSelected', data);
      } else {
        this.subject.publish(this.formState, 'changeLabelList', data);
      }
    }
  }

  disabledStartDate = (startValue: Date): boolean => {
    if (!startValue || !this.endValue) {
      return false;
    }
    return startValue.getTime() > this.endValue.getTime();
  };

  disabledEndDate = (endValue: Date): boolean => {
    if (!endValue || !this.startValue) {
      return false;
    }
    return endValue.getTime() <= this.startValue.getTime();
  };

  onStartChange(date: Date): void {
    this.startValue = this.convertDate(date, 'start');
    if (date == null) {
      this.endValue = null;
      this.formControl.patchValue([]);
    }
  }

  onEndChange(date: Date): void {
    this.endValue = this.convertDate(date, 'end');
    if (date == null) {
      this.startValue = null;
      this.formControl.patchValue([]);
    }
  }

  convertDate(date: Date, type) {
    if (!date) return null;
    let now = date; //当前日期
    let nowMonth = now.getMonth(); //当前月
    let nowYear = now.getFullYear(); //当前年
    let convertDate: Date;
    if (type == 'start') {
      convertDate = new Date(nowYear, nowMonth, 1);
    } else if (type == 'end') {
      convertDate = new Date(nowYear, nowMonth + 1, 0, 23, 59, 59);
    }
    return convertDate;
  }

  handleStartOpenChange(open: boolean): void {
    if (!open && this.startValue != null) {
      this.endOpen = true;
    }
  }

  handleEndOpenChange(open: boolean): void {
    this.endOpen = open;
    this.formControl.patchValue([this.startValue, this.endValue]);
  }

  get Rows() {
    return this.to.config.rows || 1;
  }

  get textareaValue() {
    return this.to.config.value || '请填写重要提示';
  }

  checkBtnStatus() {
    let customBtn = this.options.formState['customBtn'];
    let showBtn;
    if (customBtn) {
      showBtn = customBtn.find((btn) => {
        return btn.operationId == this.key;
      });
    } else {
      showBtn = false;
    }
    if (showBtn) {
      this.btnLoading = showBtn.loading;
    }
    return showBtn;
  }

  checkDefaultValue(check = true) {
    if (this.model.hasOwnProperty(this.key) && this.to['defaultValue'] != this.model[this.key] && check) {
      this.value = this.model[this.key];
    } else {
      this.value = this.to['defaultValue'];
    }

    const config = this.to.config;
    switch (config.type) {
      case 'radio':
        if (this.to['defaultValue'] == 'all') {
          this.value = null;
          this.formControl.patchValue(null);
        }
        break;
      case 'dateRange':
        switch (this.value) {
          case '':
            this.formControl.patchValue([new Date(), new Date()]);
            break;
          case '7':
            this.formControl.patchValue([addDays(new Date(), -6), endOfDay(new Date())]);
            break;
          case '30':
            this.formControl.patchValue([addDays(new Date(), -29), endOfDay(new Date())]);
            break;
          case '90':
            this.formControl.patchValue([addDays(new Date(), -89), endOfDay(new Date())]);
            break;
          default :
            this.formControl.patchValue([new Date(), new Date()]);
            break;
        }
        break;
      case 'date':
        this.formControl.patchValue(new Date());
        break;
      case 'boolean':
        this.value = toBoolean(this.value);
        break;
      case 'select':
        if (this.value.indexOf('ctx.') > -1) {
          this.value = this.expressionService.evaluate(this.to['defaultValue'], { context: this.formState }, false);
          if (this.value) {
            this.items = [this.value];
            this.formControl.patchValue(this.value[this.bindValue]);
          } else {
            this.formControl.patchValue(null);
          }
        }
        if (this.value.indexOf('{') > -1) {
          let value = deepClone(getO(this.value));
          if (typeof value === 'object') {
            this.value = value[this.platform];
            this.formControl.patchValue(this.value);
            this.model[this.key] = value[this.platform];
          }
        }
        if (this.value.indexOf('[') > -1) {
          // tslint:disable-next-line:no-eval
          let value = deepClone(eval(this.value));
          this.value = value;
          this.formControl.patchValue(this.value);
          this.model[this.key] = value;
        }
        break;
      default :
        break;
    }
    if (!check) {
      if (config.type == 'dateRange') {
        this.formControl.patchValue([new Date(), new Date()]);
      } else if (config.type == 'date') {
        this.formControl.patchValue(new Date());
      } else {
        this.formControl.patchValue(this.value);
      }
    }
  }

}
